using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using JGSY.CMS.LowCode.Platform.Application.DTOs;
using JGSY.CMS.LowCode.Platform.Application.Services;

namespace JGSY.CMS.LowCode.Platform.Controllers
{
    /// <summary>
    /// 审计日志相关接口。
    /// 提供审计日志的增删查及条件查询、统计分析、管理维护等完整的 API。
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    public class AuditLogController : ControllerBase
    {
        private readonly IAuditLogAppService _service;
        private readonly ILogger<AuditLogController> _logger;

        /// <summary>
        /// 构造函数，注入审计日志服务
        /// </summary>
        /// <param name="service">审计日志应用服务接口</param>
        /// <param name="logger">日志服务</param>
        public AuditLogController(IAuditLogAppService service, ILogger<AuditLogController> logger)
        {
            _service = service;
            _logger = logger;
        }

        /// <summary>
        /// 获取所有审计日志
        /// </summary>
        /// <returns>审计日志列表</returns>
        [HttpGet]
        public async Task<ActionResult<IEnumerable<AuditLogDto>>> GetAll()
        {
            try
            {
                var result = await _service.GetAllAsync();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting all audit logs");
                return StatusCode(500, "Internal server error");
            }
        }

        /// <summary>
        /// 根据ID获取审计日志
        /// </summary>
        /// <param name="id">审计日志主键</param>
        /// <returns>审计日志数据</returns>
        [HttpGet("{id:long}")]
        public async Task<ActionResult<AuditLogDto>> GetById([FromRoute] long id)
        {
            try
            {
                if (id <= 0)
                {
                    return BadRequest("Invalid audit log ID");
                }

                var result = await _service.GetByIdAsync(id);
                if (result == null)
                {
                    return NotFound($"Audit log with ID {id} not found");
                }

                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting audit log by ID {Id}", id);
                return StatusCode(500, "Internal server error");
            }
        }

        /// <summary>
        /// 分页获取审计日志
        /// </summary>
        /// <param name="pageIndex">页索引，从1开始</param>
        /// <param name="pageSize">页大小，默认20，最大100</param>
        /// <param name="type">操作类型过滤</param>
        /// <param name="userId">用户ID过滤</param>
        /// <param name="resource">资源过滤</param>
        /// <returns>分页结果</returns>
        [HttpGet("paged")]
        public async Task<ActionResult<object>> GetPaged(
            [FromQuery] int pageIndex = 1, 
            [FromQuery] int pageSize = 20, 
            [FromQuery] string? type = null, 
            [FromQuery] string? userId = null, 
            [FromQuery] string? resource = null)
        {
            try
            {
                if (pageIndex <= 0) pageIndex = 1;
                if (pageSize <= 0 || pageSize > 100) pageSize = 20;

                var (items, totalCount) = await _service.GetPagedAsync(pageIndex, pageSize, type, userId, resource);
                
                var result = new
                {
                    Items = items,
                    TotalCount = totalCount,
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    TotalPages = (int)Math.Ceiling((double)totalCount / pageSize)
                };

                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting paged audit logs");
                return StatusCode(500, "Internal server error");
            }
        }

        /// <summary>
        /// 添加审计日志
        /// </summary>
        /// <param name="dto">审计日志数据传输对象</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        public async Task<IActionResult> Add([FromBody] AuditLogDto dto)
        {
            try
            {
                if (dto == null)
                {
                    return BadRequest("Audit log data is required");
                }

                if (string.IsNullOrEmpty(dto.Type))
                {
                    return BadRequest("Operation type is required");
                }

                await _service.AddAsync(dto);
                return Created("", "Audit log created successfully");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error adding audit log");
                return StatusCode(500, "Internal server error");
            }
        }

        /// <summary>
        /// 批量添加审计日志
        /// </summary>
        /// <param name="dtos">审计日志数据列表</param>
        /// <returns>操作结果</returns>
        [HttpPost("batch")]
        public async Task<IActionResult> BatchAdd([FromBody] IEnumerable<AuditLogDto> dtos)
        {
            try
            {
                if (dtos == null)
                {
                    return BadRequest("Audit log data is required");
                }

                await _service.BatchAddAsync(dtos);
                return Ok("Audit logs created successfully");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error batch adding audit logs");
                return StatusCode(500, "Internal server error");
            }
        }

        /// <summary>
        /// 条件查询审计日志
        /// </summary>
        /// <param name="type">日志类型</param>
        /// <param name="userId">用户主键</param>
        /// <param name="start">起始时间</param>
        /// <param name="end">结束时间</param>
        /// <param name="resource">资源标识</param>
        /// <returns>审计日志列表</returns>
        [HttpGet("query")]
        public async Task<ActionResult<IEnumerable<AuditLogDto>>> Query(
            [FromQuery] string type = "", 
            [FromQuery] long userId = 0, 
            [FromQuery] DateTime? start = null, 
            [FromQuery] DateTime? end = null, 
            [FromQuery] string resource = "")
        {
            try
            {
                var result = await _service.QueryAsync(type, userId, start, end, resource);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error querying audit logs");
                return StatusCode(500, "Internal server error");
            }
        }

        /// <summary>
        /// 获取审计日志统计信息
        /// </summary>
        /// <returns>统计信息</returns>
        [HttpGet("statistics")]
        public async Task<ActionResult<AuditLogStatisticsDto>> GetStatistics()
        {
            try
            {
                var statistics = await _service.GetStatisticsAsync();
                return Ok(statistics);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting audit log statistics");
                return StatusCode(500, "Internal server error");
            }
        }

        /// <summary>
        /// 清理过期的审计日志
        /// </summary>
        /// <param name="retentionDays">保留天数，默认90天</param>
        /// <returns>被清理的记录数</returns>
        [HttpDelete("cleanup")]
        public async Task<ActionResult<object>> Cleanup([FromQuery] int retentionDays = 90)
        {
            try
            {
                if (retentionDays <= 0)
                {
                    return BadRequest("Retention days must be greater than 0");
                }

                var deletedCount = await _service.CleanupAsync(retentionDays);
                
                return Ok(new 
                { 
                    DeletedCount = deletedCount, 
                    RetentionDays = retentionDays,
                    Message = $"Successfully cleaned up {deletedCount} audit logs older than {retentionDays} days"
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error cleaning up audit logs");
                return StatusCode(500, "Internal server error");
            }
        }

        /// <summary>
        /// 记录操作审计日志的便捷接口
        /// </summary>
        /// <param name="request">日志记录请求</param>
        /// <returns>操作结果</returns>
        [HttpPost("log-operation")]
        public async Task<IActionResult> LogOperation([FromBody] LogOperationRequest request)
        {
            try
            {
                if (request == null || string.IsNullOrEmpty(request.OperationType) || string.IsNullOrEmpty(request.Content))
                {
                    return BadRequest("Operation type and content are required");
                }

                await _service.LogOperationAsync(
                    request.OperationType,
                    request.Content,
                    request.UserId,
                    request.UserName,
                    request.IP,
                    request.Resource,
                    request.Result ?? "Success",
                    request.Exception);

                return Ok("Operation logged successfully");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error logging operation");
                return StatusCode(500, "Internal server error");
            }
        }
    }

    /// <summary>
    /// 记录操作日志请求模型
    /// </summary>
    public class LogOperationRequest
    {
        /// <summary>
        /// 操作类型
        /// </summary>
        [Required]
        public string OperationType { get; set; } = string.Empty;

        /// <summary>
        /// 操作内容
        /// </summary>
        [Required]
        public string Content { get; set; } = string.Empty;

        /// <summary>
        /// 用户ID
        /// </summary>
        public string? UserId { get; set; }

        /// <summary>
        /// 用户名
        /// </summary>
        public string? UserName { get; set; }

        /// <summary>
        /// IP地址
        /// </summary>
        public string? IP { get; set; }

        /// <summary>
        /// 操作资源
        /// </summary>
        public string? Resource { get; set; }

        /// <summary>
        /// 操作结果
        /// </summary>
        public string? Result { get; set; }

        /// <summary>
        /// 异常信息
        /// </summary>
        public string? Exception { get; set; }
    }
}
